﻿Imports Microsoft.VisualBasic

Namespace MyApp
    Namespace Network
        Public Class Linkedin
            Private db As mDB = mDB.GetDB
            Public Property oauth2 As WebApi.Oauth.Oauth2

            Public Function RedirectAuth() As String

                Return oauth2.GetDialog("https://www.linkedin.com/uas/oauth2/authorization", "rw_company_admin r_network")

                'Redirigo l'utente a twitter che ha capito chi sono e verifica se l'utente è loggato e se sì controlla che abbia l'autorizzazione con la mia applicazione
                'Return SF("https://www.facebook.com/dialog/oauth?client_id={0}&redirect_uri={1}", oauth2.client_id, HttpUtility.UrlEncode(oauth2.redirect_uri))

            End Function



            Public Sub AddLogin(code As String, access_token As String)
                Dim db = mDB.GetDB
                Dim CurrUser = MyApp.GetUser(False)

                oauth2.access_token = access_token
                oauth2.code = code

                If access_token = "" Then
                    oauth2.ConfirmingIdentity("https://www.linkedin.com/uas/oauth2/accessToken", "POST", "JSON")
                End If

                Dim tc = New WebApi.Linkedin.LinkedinClient(oauth2)


                '--------------------------------------------------
                ' creo user_account

                Dim CurrPeople = tc.GetCurrUser
                Dim PeopleAcc = Me.UpdateAccountPeople(CurrPeople)

                Dim UserPeopleAcc = CurrUser.Tab_User_Account.BY.User_Account.Account_Id(PeopleAcc.Id).Limit(1).ToObj

                If UserPeopleAcc Is Nothing Then
                    UserPeopleAcc = New mDB.User_Account
                    db.TAB.User_Account.InsertOnSubmit(UserPeopleAcc)
                End If

                UserPeopleAcc.Account_Id = PeopleAcc.Id
                UserPeopleAcc.User_Id = CurrUser.Id
                'UserPeopleAcc.Network_Id = AccType.LINKEDIN_PEOPLE
                'UserPeopleAcc.Oauth_Consumer_Key = oauth2.client_id
                'UserPeopleAcc.Oauth_Consumer_Secret = oauth2.client_secret
                'UserPeopleAcc.Oauth_Token = oauth2.access_token

                db.SubmitChanges()


                '-------------------------------------------------
                'crea account delle company
                Dim AdminCompanies = tc.GetCompaniesAdmin

                For Each Company In AdminCompanies.values

                    ' creo account
                    Dim CompanytAcc = Me.UpdateAccountCompany(Company)

                    ' creo user_account
                    Dim UserCompanyAcc = CurrUser.Tab_User_Account.BY.User_Account.Account_Id(CompanytAcc.Id).Limit(1).ToObj

                    If UserCompanyAcc Is Nothing Then
                        UserCompanyAcc = New mDB.User_Account
                        db.TAB.User_Account.InsertOnSubmit(UserCompanyAcc)
                    End If

                    UserCompanyAcc.Account_Id = CompanytAcc.Id
                    UserCompanyAcc.User_Id = CurrUser.Id
                    'UserCompanyAcc.Network_Id = AccType.LINKEDIN_COMPANY
                    'UserCompanyAcc.Oauth_Consumer_Key = oauth2.client_id
                    'UserCompanyAcc.Oauth_Consumer_Secret = oauth2.client_secret
                    'UserCompanyAcc.Oauth_Token = oauth2.access_token

                    db.SubmitChanges()

                Next

            End Sub

            Public Function DownloadAccountsPeople(ids As List(Of String)) As List(Of mDB.Account)
                Dim lk = New WebApi.Linkedin.LinkedinClient(Me.oauth2)
                Dim NumUserPerRequest = 50
                Dim Accounts As New List(Of mDB.Account)


                Dim page = Int((ids.Count - 1) / NumUserPerRequest) + 1

                For ct = 1 To page

                    Dim Numids = NumUserPerRequest
                    If ct = page Then
                        Numids = ids.Count - ((page - 1) * NumUserPerRequest)
                    End If

                    Dim IdsLookup = String.Join(",", ids.GetRange((ct - 1) * NumUserPerRequest, Numids))

                    Dim tusers = lk.GetUsersLookup(IdsLookup)

                    MyApp.WriteProcLog(SF("(tab)(tab)update number user: {0}", Numids), Task.TaskType.UPDATE_ACCOUNTS)

                    For Each tu In tusers.values

                        Dim Acc = Me.UpdateAccountPeople(tu)
                        Accounts.Add(Acc)

                    Next

                Next

                Return Accounts

            End Function

            Public Function DownloadAccountsCompanies(ids As List(Of String)) As List(Of mDB.Account)
                Dim lk = New WebApi.Linkedin.LinkedinClient(Me.oauth2)
                Dim NumUserPerRequest = 50
                Dim Accounts As New List(Of mDB.Account)


                Dim page = Int((ids.Count - 1) / NumUserPerRequest) + 1

                For ct = 1 To page

                    Dim Numids = NumUserPerRequest
                    If ct = page Then
                        Numids = ids.Count - ((page - 1) * NumUserPerRequest)
                    End If

                    'Dim tusers As List(Of WebApi.Twitter.User)
                    Dim IdsLookup = String.Join(",", ids.GetRange((ct - 1) * NumUserPerRequest, Numids))

                    Dim tusers = lk.GetCompaniesLookup(IdsLookup)

                    'MyApp.WriteProcLog(SF("(tab)(tab) {0} - {1} - {2}", tusers.values.Count, IdsLookup, lk.LastRes), AutoProcType.UPDATE_ACCOUNTS)

                    MyApp.WriteProcLog(SF("(tab)(tab)update number user: {0}", Numids), Task.TaskType.UPDATE_ACCOUNTS)

                    For Each tu In tusers.values

                        MyApp.WriteProcLog(SF("(tab)(tab)(tab)user: {0} - {1} ", tu.id, tu.name), Task.TaskType.UPDATE_ACCOUNTS)


                        Dim Acc = Me.UpdateAccountCompany(tu)
                        Accounts.Add(Acc)

                    Next

                Next

                Return Accounts

            End Function

            Public Sub DownloadAccountFollowers(Acc As mDB.Account)
                Dim lk = New WebApi.Linkedin.LinkedinClient(Me.oauth2)


                Dim conn = lk.GetUserConnections(Acc.Account_Code)

                For Each p In conn.values

                    Acc.AddAccountLink(mDB._Account_Link.Type.FOLLOWER, p.id, AccType.LINKEDIN_PEOPLE)

                    Me.UpdateAccountPeople(p)

                Next

                Acc.Account_Update.Follower_Update = Now
                Acc.Account_Update.Follower_Update_Count = Acc.Account_Add_Info.Follower_Count
                db.SubmitChanges()


                ''prendo l'ulmito cursor
                'Dim Cursor = Acc.Account_Update.Follower_Last_Code

                'If Cursor = "" Then Cursor = "-1"

                'Do
                '    'scarico i followers
                '    Dim Foll = tc.GetFollowers("", Acc.Account_Code, Cursor)

                '    MyApp.WriteProcLog(SF("(tab)(tab)update followers: {1}", Acc.Fullname, Foll.ids.Count), AutoProcType.UPDATE_ACCOUNTS)

                '    For Each f In Foll.ids

                '        Acc.AddAccountLink(mDB.Account_Link.Type.FOLLOWER, f, NetAccType.TWITTER_ACCOUNT)

                '    Next
                '    Cursor = Foll.next_cursor_str

                '    '-------------------------------------------------------------
                '    'aggiona il link_update
                '    Acc.Account_Update.Follower_Last_Code = Cursor

                '    db.SubmitChanges()

                'Loop Until Cursor = "0"

                '' se ho finito aggiorno tutto
                'If Cursor = "0" Then
                '    ' mofifico in olf followre
                '    'db.TAB.Account_Link.
                '    '    BY.Account_Link.Account_Id(Acc.Id, mDB.Account_Link.Type.FOLLOWER).
                '    '    Where("updating", "=", False).
                '    'Delete.ExecuteCommand()

                '    db.TAB.Account_Link.
                '        BY.Account_Link.Account_Id(Acc.Id, mDB.Account_Link.Type.FOLLOWER).
                '        Where("updating", "=", False).
                '    Update.UpdateValue("link_type_id", mDB.Account_Link.Type.FOLLOWER_OLD).ExecuteCommand()

                '    'imposto gli aggiornati a 0
                '    db.TAB.Account_Link.
                '        BY.Account_Link.Account_Id(Acc.Id, mDB.Account_Link.Type.FOLLOWER).
                '    Update.UpdateValue("updating", 0).ExecuteCommand()

                '    'aggiorno il linkupdate
                '    Acc.Account_Update.Follower_Last_Code = ""
                '    Acc.Account_Update.Follower_Update_Date = Now
                '    Acc.Account_Update.Follower_Update_Count = Acc.Account_Update.Follower_Count

                '    db.SubmitChanges()

                'End If


            End Sub

            Public Function UpdateAccountCompany(tu As WebApi.Linkedin.Company) As mDB.Account

                '--------------------------------------------
                ' creo account
                Dim Acc = mDB.Account.GetForUpdate(tu.id, AccType.LINKEDIN_COMPANY)


                Acc.Fullname = tu.name
                Acc.Username = tu.universalname
                Acc.Avatar = tu.squarelogourl
                'If tu.location IsNot Nothing Then
                '    Acc.Location = tu.location.name
                'End If
                Acc.Description = MyApp.ToUTF8DB(tu.description)
                Acc.Url = tu.websiteurl

                Acc.Account_Add_Info.Profile_Update = Now
                Acc.Account_Add_Info.Follower_Count = tu.numfollowers

                db.SubmitChanges()

                Return Acc

            End Function

            Public Function UpdateAccountPeople(tu As WebApi.Linkedin.People) As mDB.Account

                '--------------------------------------------
                ' creo account
                Dim Acc = mDB.Account.GetForUpdate(tu.id, AccType.LINKEDIN_PEOPLE)


                Acc.Fullname = tu.formattedname
                Acc.Username = ""
                Acc.Avatar = tu.pictureurl
                'If tu.location IsNot Nothing Then
                '    Acc.Location = tu.location.name
                'End If
                Acc.Description = MyApp.ToUTF8DB(tu.headline)
                Acc.Url = tu.publicprofileurl

                Acc.Account_Add_Info.Profile_Update = Now
                Acc.Account_Add_Info.Follower_Count = tu.numconnections

                db.SubmitChanges()

                Return Acc

            End Function


            'Public Sub DownloadAccountMessages(Acc As mDB.Account)

            '    Const NumMessFindEnd = 100
            '    Const NumPostToDownload = 500
            '    'creo il client con i dati dell'account collegato
            '    Dim tc = New WebApi.Linkedin.LinkedinClient(Me.oauth2)

            '    Dim EndDownload = False
            '    Dim ContinuePrevDownload = False
            '    Dim Since = ""
            '    Dim Until = ""

            '    Dim PostCount = 0

            '    Dim Codes = Acc.Account_Update.Message_Last_Code.ToString.Split(",")

            '    If Codes.Length > 1 Then
            '        ContinuePrevDownload = True
            '        Since = Codes(0)
            '        Until = Codes(1)
            '    Else
            '        Since = Acc.GetLastMessageDateUniversalTimeStamp ' Me.GetLastMessCod(Acc)
            '    End If

            '    MyApp.WriteProcLog(SF("(tab)(tab)LINKEDIN begin update message: {0} ({1})", Acc.Fullname, Acc.Username), AutoProcType.UPDATE_ACCOUNTS)

            '    EndDownload = False
            '    Do Until EndDownload

            '        Dim tweets As WebApi.Linkedin.Results(Of WebApi.Linkedin.Update(Of WebApi.Linkedin.companyStatusUpdate))

            '        Try

            '            tweets = tc.GetCompanyPosts(Acc.Account_Code) 'Acc.Account_Code 154096

            '            PostCount += 1

            '            'Exit Do

            '        Catch ex As WebApi.Net.ExceptionRequest

            '            'MyApp.WriteProcLog(SF("(tab)(tab)(tab)ExceptionRequest message: {0}, {1}", tc.LastError.Code, tc.LastError.Message), AutoProcType.UPDATE_ACCOUNTS)
            '            Exit Do

            '        End Try

            '        MyApp.WriteProcLog(SF("(tab)(tab)(tab)message: {0}, {1}", tweets.values.Count, Acc.Username), AutoProcType.UPDATE_ACCOUNTS)

            '        For Each t In tweets.values
            '            Me.UpdateMessagePost(Acc, t)
            '        Next

            '        If tweets.values.Count > 0 Then
            '            Until = Utils.Conv.ToTimeStamp(tweets.values.Last.timestamp.ToUniversalTime) ' tweets.Last.id_str
            '        End If

            '        Acc.Account_Update.Message_Last_Code = SF("{0},{1}", Since, Until)
            '        db.SubmitChanges()

            '        If tweets.values.Count <= NumMessFindEnd Or PostCount > NumPostToDownload Then
            '            EndDownload = True
            '        End If

            '        If EndDownload And ContinuePrevDownload Then
            '            ContinuePrevDownload = False
            '            EndDownload = False
            '            Since = Acc.GetLastMessageDateUniversalTimeStamp ' Me.GetLastMessCod(Acc)
            '            Until = ""
            '        End If

            '    Loop

            '    If EndDownload Then
            '        'Acc.Account_Update.Message_Update_Date = Now
            '        Acc.Account_Update.Message_Last_Code = ""
            '        'IMPORTANTE se vengono scaricati dei messaggi rimette a 0 la data di aggiornamento dei profili connessi in modo che i trend vengano creati solo quando tutti gli accorunt sono stati scaricati
            '        Acc.Account_Update.Profile_Related_Update = Date.MinValue
            '        db.SubmitChanges()
            '    End If

            '    MyApp.WriteProcLog(SF("(tab)(tab)end update message: {0} ({1})", Acc.Fullname, Acc.Username), AutoProcType.UPDATE_ACCOUNTS)

            'End Sub

            Public Sub DownloadAccountPosts(Acc As mDB.Account)

                Const NumPostFindEnd = 100
                Const NumPostToDownload = 500
                'creo il client con i dati dell'account collegato
                Dim tc = New WebApi.Linkedin.LinkedinClient(Me.oauth2)

                Dim EndDownload = False
                Dim ContinuePrevDownload = False
                Dim Since = ""
                Dim Until = ""

                Dim IsUserAccount = Acc.Tab_User_Account.ToList.Count > 0

                Dim PostCount = 0

                Dim Codes = Acc.Account_Add_Info.Post_Last_Code.ToString.Split(",")

                If Codes.Length > 1 Then
                    ContinuePrevDownload = True
                    Since = Codes(0)
                    Until = Codes(1)
                Else
                    Since = Acc.GetLastPostDateUniversalTimeStamp ' Me.GetLastMessCod(Acc)
                End If

                MyApp.WriteProcLog(SF("(tab)(tab)LINKEDIN begin update post: {0} ({1})", Acc.Fullname, Acc.Username), Task.TaskType.UPDATE_ACCOUNTS)

                EndDownload = False
                Do Until EndDownload

                    Dim tweets As WebApi.Linkedin.Results(Of WebApi.Linkedin.Update(Of WebApi.Linkedin.companyStatusUpdate))

                    Try

                        tweets = tc.GetCompanyPosts(Acc.Account_Code) ', Since, Until)

                    Catch ex As WebApi.Net.ExceptionAPIResponse

                        ' MyApp.WriteProcLog(SF("(tab)(tab)(tab)ExceptionRequest message: {0}, {1}", tc.LastError.Code, tc.LastError.Message), AutoProcType.UPDATE_ACCOUNTS)
                        Exit Do

                    End Try

                    MyApp.WriteProcLog(SF("(tab)(tab)(tab)post: {0}, {1}", tweets.values.Count, Acc.Username), Task.TaskType.UPDATE_ACCOUNTS)

                    PostCount += tweets.values.Count
                    For Each t In tweets.values
                        Me.UpdateAccountPost(Acc, t, IsUserAccount)
                    Next

                    If tweets.values.Count > 0 Then
                        Until = Utils.Conv.ToTimeStamp(tweets.values.Last.timestamp.ToUniversalTime) ' tweets.Last.id_str
                    End If

                    Acc.Account_Add_Info.Post_Last_Code = SF("{0},{1}", Since, Until)
                    db.SubmitChanges()

                    If tweets.values.Count <= NumPostFindEnd Or PostCount > NumPostToDownload Then
                        EndDownload = True
                    End If

                    If EndDownload And ContinuePrevDownload Then
                        ContinuePrevDownload = False
                        EndDownload = False
                        Since = Acc.GetLastPostDateUniversalTimeStamp ' Me.GetLastMessCod(Acc)
                        Until = ""
                        PostCount = 0
                    End If

                Loop

                If EndDownload Then
                    Acc.Account_Add_Info.Post_Update = Now
                    Acc.Account_Add_Info.Post_Last_Code = ""
                    db.SubmitChanges()
                End If

                MyApp.WriteProcLog(SF("(tab)(tab)end update post: {0} ({1})", Acc.Fullname, Acc.Username), Task.TaskType.UPDATE_ACCOUNTS)

            End Sub

            Public Function UpdateAccountPost(Acc As mDB.Account, t As WebApi.Linkedin.Update(Of WebApi.Linkedin.companyStatusUpdate), SaveEntities As Boolean) As mDB._Account_Post

                'aggiorna messaggio
                Dim Post = Acc._Tab_Account_Post.BY._Account_Post._Post_Code(t.updateKey).ToObj

                If Post Is Nothing Then
                    Post = New mDB._Account_Post
                    db.InsertOnSubmit(Acc.ArchivePost.Table_Name, Post)
                End If

                Post.Post_Code = t.updateKey
                Post.Post_Text = MyApp.ToUTF8DB(t.updateContent.companystatusupdate.share.comment) 'Encoding.Default.GetString(Encoding.Convert(Encoding.UTF8, Encoding.Default, Encoding.UTF8.GetBytes(t.text)))
                Post.Pubb_Date = t.timestamp
                Post.Account_Id = Acc.Id

                db.SubmitChanges()

                '-------------------------------------------------------
                ' messaggi
                ' IMPORTANTE se un post è una risposta ad un altro messaggio mette il post anche tra i messaggi
                If SaveEntities Then
                    If t.updateContent.company.id <> Acc.Account_Code Or t.updatecomments IsNot Nothing Then
                        Me.UpdateMessagePost(Acc, t)
                    End If
                End If

                Return Post

            End Function

            Public Function UpdateMessagePost(Acc As mDB.Account, t As WebApi.Linkedin.Update(Of WebApi.Linkedin.companyStatusUpdate)) As mDB.Message_Post

                'aggiorna messaggio
                Dim Mess = db.TAB.Message_Post.BY.Message_Post.Post_Code(t.updateKey).ToObj

                If Mess Is Nothing Then
                    Mess = New mDB.Message_Post

                    '-------------------------------------------------------------
                    'crea l'account
                    Dim AccCode = t.updateContent.company.id '    t.from.id '  t.user.id_str
                    If AccCode <> "" Then

                        Dim MessAcc = Acc.AddAccountLink(mDB._Account_Link.Type.FOLLOWER, AccCode, AccType.LINKEDIN_COMPANY)

                        Mess.Account_Id = MessAcc.Account_Link_Id
                    Else

                        Mess.Account_Id = 0

                    End If

                    db.InsertOnSubmit(Mess)

                End If

                Mess.Post_Code = t.updateKey
                If Mess.Account_Id <> Acc.Id Then
                    Mess.To_Account_Id = Acc.Id
                Else
                    Mess.To_Account_Id = 0
                End If

                Mess.Post_Text = MyApp.ToUTF8DB(t.updateContent.companystatusupdate.share.comment) '& " (" & MyApp.ToUTF8DB(t.story) & ")" & " [" & t.type.ToUpper & "]" ' Encoding.Default.GetString(Encoding.Convert(Encoding.UTF8, Encoding.Default, Encoding.UTF8.GetBytes(t.text)))
                Mess.Pubb_Date = t.timestamp
                Mess.Hash_Id = Mess.Post_Text.GetHashCode

                db.SubmitChanges()

                'commenti
                If t.updatecomments IsNot Nothing Then

                    For Each comm In t.updatecomments.values
                        Dim m = Me.UpdateCommentPost(Acc, Mess, comm)
                    Next

                End If

                Return Mess

            End Function
            Public Function UpdateCommentPost(Acc As mDB.Account, Parent As mDB.Message_Post, t As WebApi.Linkedin.Comment) As mDB.Message_Post

                'aggiorna messaggio
                Dim Mess = db.TAB.Message_Post.BY.Message_Post.Post_Code(t.id).ToObj

                If Mess Is Nothing Then
                    Mess = New mDB.Message_Post

                    '-------------------------------------------------------------
                    'crea l'account
                    Dim IsPeople = t.person IsNot Nothing

                    Dim AccCode = ""
                    If IsPeople Then
                        AccCode = t.person.id
                    Else
                        AccCode = t.company.id
                    End If

                    If AccCode <> "" Then

                        Dim MessAcc = Acc.AddAccountLink(mDB._Account_Link.Type.FOLLOWER, AccCode, IIf(IsPeople, AccType.LINKEDIN_PEOPLE, AccType.LINKEDIN_COMPANY))

                        Mess.Account_Id = MessAcc.Account_Link_Id ' MessAcc.Id
                    Else

                        Mess.Account_Id = 0

                    End If

                    db.InsertOnSubmit(Mess)

                    Mess.Post_Code = t.id
                    Mess.To_Account_Id = Parent.Account_Id
                    Mess.Post_Text = MyApp.ToUTF8DB(t.comment) ' Encoding.Default.GetString(Encoding.Convert(Encoding.UTF8, Encoding.Default, Encoding.UTF8.GetBytes(t.text)))
                    Mess.Pubb_Date = t.timestamp
                    Mess.Hash_Id = Mess.Post_Text.GetHashCode
                    Mess.Reply_To_Post_Code = Parent.Post_Code
                    Mess.Parent_Post_Update = 1

                    db.SubmitChanges()

                    Return Mess

                Else

                    Return Nothing

                End If

            End Function


        End Class

    End Namespace
End Namespace
